;	void blit(Uint8 *screen, int s_w, int s_h, Uint8 *image, int i_w, int i_h, int x, int y, Color color_off);

global blit

%define blit_screen	dword[ebp+8]	;4bytes
%define s_w		dword[ebp+12]	;4bytes
%define s_h		dword[ebp+16]	;4bytes
%define blit_image	dword[ebp+20]	;4bytes
%define i_w		dword[ebp+24]	;4bytes
%define i_h		dword[ebp+28]	;4bytes
%define x		dword[ebp+32]	;4bytes
%define y		dword[ebp+36]	;4bytes
%define color_off	dword[ebp+40]	;4bytes


section .data
mascaraInversora: dq 0xffffffffffffffff,0xfffffffffffffff
filtroCanalAlfa: dq 0x00ffffff00ffffff,0x00ffffff00ffffff

doscincocinco: dd 255.0
mascara_dwordBajo:	dq 0x0000000000000000, 0x0000000000000000
mascara_bytesBajos:	dq 0x000000ff000000ff, 0x000000ff000000ff
shuffleDwordBajo: dq 0x000000000C080400,0x0000000000000000
	
section .text
blit:
		push ebp
		mov ebp, esp
		sub esp, 8
		push edi
		push esi
		push ebx
		push ecx
		push edx

		
		; C -->color transparente
		; XMM0 = 0 0 0 C
		movd xmm0, color_off
		shufps xmm0, xmm0,0
		
		movdqu xmm4, [mascaraInversora]
		movdqu xmm5, [filtroCanalAlfa]
		
		andps xmm0, xmm5
		
		mov ebx, i_w
		shl ebx, 2			; ebx ---> 4 i_w
		
		; esi = puntero al primer byte del sprite
		mov esi, blit_image
		
		; edi = posicion inicial en pantalla = screen + 4 * y * s_w +  4* x
		mov eax, y
		mul s_w
		add eax, x
		shl eax, 2
		mov edi, blit_screen
		add edi, eax		
		
		mov eax, s_w
		shl eax, 2
	
		; itero sobre las filas (del sprite)
		xor ecx, ecx			;  i =  [0 .. i_h)
		.ciclo_filas:

				; itero sobre las columnas (del sprite)	
				xor edx, edx			;j = [0 .. 4*i_w)
				.ciclo_columnas:
						
						; XMM1 ---> pixeles SPRITE
						; cargo 4 pixeles del sprite (16bytes)
						movdqu xmm1, [esi+edx]
						andps xmm1, xmm5	;descarto el canal alfa de la comparacion
						
						; armo la mascara, comparando cada pixel con el color transparente
						movaps xmm2, xmm1
						cmpeqps xmm2, xmm0
				
						; XMM3 ---> pixeles FONDO
						; cargo 4 pixeles del fondo
						movdqu xmm3, [edi+edx]
						
						; aplico la mascara al fondo
						andps xmm3, xmm2
						
						; invierto la mascara y la aplico al sprite
						xorps xmm2, xmm4						
						andps xmm1, xmm2						

						; combino los pixeles
						orps xmm1, xmm3
						
						; actualizo los 4 pixeles
						movdqu [esi+edx], xmm1
						
						lea edx, [edx+16]		; j = j + 16
						cmp edx, ebx
						jne .ciclo_columnas		; si j = 4 * s_w, salgo
				
				add esi, ebx
				add edi, eax

				inc ecx
				cmp ecx, i_h
				jne .ciclo_filas



		pop edx
		pop ecx
		pop ebx
		pop esi
		pop edi
		add esp, 8
		pop ebp
		ret





global copiar

%define img1_copiar [ebp+8]
%define screen_w_copiar [ebp+12]
%define screen_h_copiar [ebp+16]
%define img2_copiar [ebp+20]




copiar:
	push ebp
	mov ebp,esp
	push esi
	push edi
	push ebx

	xor edx,edx
	xor ecx,ecx		;int i=4
	mov dword esi, img1_copiar		;esi es puntero a buffer entrara
	mov dword edi, img2_copiar		;edi puntero a buffer salida
	mov dword ebx, screen_w_copiar
	mov dword eax, screen_h_copiar
	mul ebx
 				;en eax tengo w*h
 ;      p {$xmm0,$xmm1,$xmm2,$xmm3,$xmm4,$xmm5,$xmm6,$xmm7}

	ciclo:
	; lo que hago es copiar de a 4 registros, e incremento ecx en 64. 
		movups xmm0,[esi+ecx]
		movups xmm1,[esi+ecx+16]
		movups xmm2,[esi+ecx+32]
		movups xmm3,[esi+ecx+48]

		movups [edi+ecx],xmm0
		movups [edi+ecx+16],xmm1
		movups [edi+ecx+32],xmm2
		movups [edi+ecx+48],xmm3
		add ecx,64
		cmp ecx,eax
		jne ciclo		;si llegue a h*w salgo, sino ciclo
;fin
	pop ebx
	pop edi
	pop esi
	pop ebp
	ret



global copiarInvertido

%define img1 ebp+8
%define screen_w ebp+12
%define screen_h ebp+16
%define img2 ebp+20

copiarInvertido:
	push ebp
	mov ebp,esp
	push ebx
	push edi
	push esi
	
	mov ebx, [screen_w]
	mov esi, [img1]
	add esi, ebx
	mov edi, [img2]
	mov ecx, [screen_h]
	
	ciclo_filas:
		mov edx, ebx

		ciclo_cols:
			movdqu xmm0, [esi-16]
			shufps xmm0, xmm0, 00011011b
			movdqu [edi], xmm0;
			lea esi, [esi-16]
			lea edi, [edi+16]
			lea edx, [edx-16]
			test edx, edx
			jnz ciclo_cols
		add esi, ebx
		add esi, ebx
			
		dec ecx
		jnz ciclo_filas

	
	pop esi
	pop edi
	pop ebx
	pop ebp
	ret




global zooma

%define foto ebp + 8
%define w ebp + 12
%define h ebp + 16
%define zoom ebp + 20



section .text
zooma:
	push ebp
	mov ebp,esp
	push ebx
	push edi
	push esi
	
	mov ebx, [w]
	mov eax, [h]
	
;hago TODO dos veces, una para las filas pares y otra para las impares
;para no tener q acceder siempre memoria de a,b y a+w,b+w que seguro me
;arruina la cache
	
;filas "pares"
; 0  --> par
; 1  --> impar
; ....
; h-1--> impar
	mov edi, [foto]
	mov esi, [zoom]
	xor ecx,ecx
	
	.ciclo_filas:
		xor edx,edx
		
		.ciclo_cols:
			movq xmm0, [edi]
	
			shufps xmm0,xmm0, 01010000b

			movups [esi],xmm0
			
			add edi,8
			add esi,16
			add edx,8
			cmp edx,ebx
			jb .ciclo_cols

		add esi,ebx
		add esi,ebx
		inc ecx
		cmp ecx, eax		; seguir si no llegó a h-1
		jnz .ciclo_filas


;filas "impares"
	mov edi, [foto]
	mov esi, [zoom]
	add esi,ebx
	add esi,ebx
	xor ecx,ecx
	
	.ciclo_filas2:
		xor edx,edx
		
		.ciclo_cols2:
			movq xmm0, [edi]
		
			shufps xmm0,xmm0, 01010000b

			movups [esi],xmm0
			
			add edi,8
			add esi,16
			add edx,8
			cmp edx,ebx
			jb .ciclo_cols2

		add esi,ebx
		add esi,ebx
		inc ecx
		cmp ecx, eax
		jnz .ciclo_filas2

	
	pop esi
	pop edi
	pop ebx
	pop ebp
	ret




global generarPlasma
extern vel_horizontal_0
extern vel_vertical_0
extern screen
extern colores
%define h dword [ebp+12]
%define w dword [ebp+16]
%define pixels dword [ebp+20]

%define index dword [ebp-4]
%define h0 word [ebp-8]
%define h1 word [ebp-10]
%define v0 word [ebp-12]
%define v1 word [ebp-14]

;mask_mayor: dd 0,63,127,191
mask_mayor: dd 191,127,63,-1
;mask_menor: dd 64,128,192,256
mask_menor: dd 256,192,128,64	;256 tiene que quedar en la parte baja del xmm
;~negar: dd 0x80000000,0x80000000,0x80000000,0x80000000
;~mask_shift: dw 0xffff,0x0,0xffff,0x0,0xffff,0x0,0xffff,0x0
;~unos: dw 0x0100,0x0,0x01ff,0x0,0x0101,0x0,0x0100,0x0
;~masksub: dd 0xff000000,0x0,0xffff0000,0x0
suma: dd 1,0x1,1,1
dosbytesfinales: dd 0xffff0000,0xffff0000,0xffff0000,0xffff0000
generarPlasma:
	push ebp
	mov ebp,esp
	sub esp,14
	push ebx
	push esi
	push edi

	mov h1, 0
	xor eax, eax
	mov ax, [vel_horizontal_0]
	mov h0, ax    ;h0 = v_h  h1 = 0

	movdqu xmm6, [mask_mayor]
	movdqu xmm7, [mask_menor]

	mov ecx, h
	.ciclo_h:				
		mov ebx, colores
		
		;v0 = vel_vertical_0
		;v1 = 1		
		xor eax, eax
		mov ax, [vel_vertical_0]
		mov v0, ax
		mov word v1, 1
		
		mov esi, w
		.ciclo_w:			; 16pixeles por iteracion   :S, no paralelos. Eliminacion de saltos con funcion alfa
				
				and word v0, 0x1ff
				and word v1, 0x1ff
				
				mov ebx, colores
						
				xor edx,edx
				and word h0, 0x1ff
				and word h1, 0x1ff
				mov dx,h0
				movdqu xmm0, [ebx + 4*edx] ;h0 h0+1 h0+2 h0+3
				mov dx,h1
				movdqu xmm1, [ebx + 4*edx] ;h1 h1+1 h1+2 h1+3
				paddd xmm0,xmm1
				shufps xmm0,xmm0,0x00 ;xmm0 = h0+h1 h0+h1 h0+h1 h0+h1
		
				xor edx,edx
				mov dx,v0
				movdqu xmm1, [ebx + 4*edx]
				paddd xmm0,xmm1
				mov dx,v1
				movdqu xmm1, [ebx + 4*edx]
				paddd xmm0,xmm1 ;xmm0 = h0+h1+v0+v1 | h0+h1+ v0+1 +v1+1 | h0+h1+ v0+2 +v1+2 | h0+h1+ v0+3 +v1+3
				shufps xmm0,xmm0,0x00 ;xmm0 = h0+h1 h0+h1 h0+h1 h0+h1

				psrld xmm0, 4  ; x >> 4
				mov edx, 128
				movd xmm1, edx
				shufps xmm1,xmm1,0x0 ;128 128 128 128
				paddd xmm0, xmm1 ; index | index_1 | index_2 | index_3
				mov edx, 0xff
				movd xmm1, edx
				shufps xmm1,xmm1,0x00
				pand xmm0,xmm1 ;trunco para dejar solo bytes

				;copio en otro registro, uso 2 pixels a la vez
				movaps xmm1,xmm0

				;broadcasteo cada index en un registro
				shufps xmm0,xmm0,0xff ;index
				shufps xmm1,xmm1,0xaa ;index_1

				;temp --> index e index_1
				movdqu xmm4,xmm0
				movdqu xmm5,xmm1

				;255 - ( (index << 2) + 1 ); index << 2; 0; 1;
				;(index << 2) + 1; 255; 0; 1;
				;255 - ((index << 2) + 1); 255 - ((index << 2) + 1); 0; 1;
				;(index << 2) + 1; 0; 0; 1;

				movd eax,xmm0 ; index
				shl eax, 2			;index <<2
				inc eax
				mov edx, 255
				sub edx, eax  ;255 - ( (index << 2) + 1 )
				shl edx, 24	 ;lo muevo al primer byte
				movd xmm2,edx
				pslldq xmm2, 12		; <---- ubico,  byte 0  en el caso index<64
				;hasta acá tengo
				; eax = 0 | 0 | 0 | (index << 2) + 1
				; edx = 255 - ( (index << 2) + 1 ) | 0 | 0 | 0
				mov eax,edx		;eax =  edx
				shr eax,8		;eax =  0 | 255 - ( (index << 2) + 1 ) | 0 | 0 
				or edx,eax		;edx = 255 - ( (index << 2) + 1 ) | idem | 0 | 0
				movd xmm3,edx	
				pslldq xmm3, 4		; <---ubico, bytes 0 y 1 en el caso 128<=index<192
				por xmm2,xmm3		
				; hasta acá
				; xmm2 = caso 1 incompleto |  ?   | caso 3 'completo' | ?
				
				movd eax,xmm0
				shl eax,18				; 0  |  index << 2 |  0  |  0, tal vez con basura en donce dice 0 (quiza no)
				and eax,0x00ff0000		; 0  |  index << 2 |  0  |  0,  posta!
				movd xmm3, eax			
				pslldq xmm3, 12			; <--- ubico byte 1 en el caso index<64
				por xmm2,xmm3		
				; hasta acá
				; xmm2 = caso 1 'completo' |  ?   | caso 3 'completo' | ?				
				
				shl eax,8				; index << 2 |  0  |  0  |  0;
				add eax,0x1000000		; (index << 2) + 1 |  0  |  0  |  0;   esto es eax
				movd xmm3,eax			;
				shufps xmm3,xmm3, 01000100b ; xmm3[0 y 2] = eax   xmm3[1 y 3] = 0
				por xmm2,xmm3
				; hasta acá
				; xmm2 = caso 1 'completo' |  caso 2 incompleto   | caso 3 'completo' | caso 4 'completo'
				
				mov eax, 255
				shl eax, 16			; 0  |  255  |  0  |  0    esto es eax
				movd xmm3,eax		; ..
				pslldq xmm3,8		; ubico byte 1 del caso 64<=index<128
				por xmm2,xmm3
				; hasta acá
				; xmm2 = caso 1 'completo' |  caso 2 'completo'   | caso 3 'completo' | caso 4 'completo'
								
				movdqu xmm0,xmm2  ; xmm0 = xmm2

				movd eax,xmm1 ;index
				shl eax, 2			;index <<2
				inc eax
				mov edx, 255
				sub edx, eax  ;255 - ( (index << 2) + 1 )
				shl edx, 24 ;lo muevo al primer byte
				movd xmm2,edx
				pslldq xmm2, 12
				mov eax,edx
				shr eax,8
				or edx,eax
				movd xmm3,edx
				pslldq xmm3, 4
				por xmm2,xmm3
				movd eax,xmm0
				shl eax,18
				and eax,0x00ff0000
				movd xmm3, eax
				pslldq xmm3, 12
				por xmm2,xmm3
				shl eax,8
				add eax,0x1000000
				movd xmm3,eax
				shufps xmm3,xmm3, 01000100b
				por xmm2,xmm3
				mov eax, 255
				shl eax, 16
				movd xmm3,eax
				pslldq xmm3,8
				por xmm2,xmm3
				movdqu xmm1,xmm2
				; xmm1 = caso 1 'completo' |  caso 2 'completo'   | caso 3 'completo' | caso 4 'completo'
				


				; xmm0 = caso 1 'completo' |  caso 2 'completo'   | caso 3 'completo' | caso 4 'completo'
				; xmm4 =      index        |        index         |      index        |     index        				
				; PIXEL 1
				movaps xmm2,xmm4
				movaps xmm3,xmm4
				pcmpgtd xmm2, xmm6 ; xmm2 ---> index >= 0 | index >= 64 |index >= 128 |index >= 192
				movdqu xmm4,xmm7
				pcmpgtd xmm4, xmm3 ; xmm4 ---> index < 64 |index < 128 |index < 192 |index < 256
				pand xmm2,xmm4
				pand xmm0,xmm2 ;tengo una sola posibilidad ( ej 00 ff 00 00)
				; en xmm0 filtramos el caso correspondiente
				
				; xmm1 = caso 1 'completo' |  caso 2 'completo'   | caso 3 'completo' | caso 4 'completo'				
				; PIXEL 2
				movaps xmm4,xmm5
				movaps xmm3,xmm5
				pcmpgtd xmm4, xmm6 ; xmm4 --> index >= 0 | index >= 64 |index >= 128 |index >= 192
				movdqu xmm5,xmm7
				pcmpgtd xmm5, xmm3 ; xmm5 --> index < 64 |index < 128 |index < 192 |index < 256
				pand xmm4,xmm5
				pand xmm1,xmm4
				; en xmm1 filtramos el caso correspondiente				
								
				phaddd xmm0, xmm0
				phaddd xmm0, xmm0
				phaddd xmm1, xmm1
				phaddd xmm1, xmm1
				
				movdqu xmm2,[suma]
				paddd xmm0, xmm2
				paddd xmm1, xmm2
				
				; en xmm2 y xmm3 tengo un dword con el pixel correcto y en los demas 000...01
								
				mov eax,pixels
				movd edx, xmm0
				movd edi, xmm1
				bswap edx
				bswap edi
				mov [eax],edx
				mov [eax+4],edi
				
				add pixels,4
				add word v0,1
				add word v1,1
				sub esi,1

				test esi, esi
				jnz .ciclo_w
				
		add word h0,1
		add word h1,1
		dec ecx
		test ecx, ecx
		jnz .ciclo_h

	
	add word [vel_vertical_0], 4
	add word [vel_horizontal_0], 5
	

	
	pop edi
	pop esi
	pop ebx
	add esp,14
	pop ebp
	ret






global negative

%define screen	dword[ebp+8]
%define w		dword[ebp+12]
%define h		dword[ebp+16]

%define h_1			dword[ebp-4]
%define w_1			dword[ebp-8]

%macro cuatroBytesACuatroDwords 1
	PUNPCKLBW %1, %1		; 0000 0000 0000 RGBA ---> 0000 0000 RRGG BBAA
	PUNPCKLBW %1, %1		; 0000 0000 RRGG BBAA ---> RRRR GGGG BBBB AAAA
	andps %1, xmm5
%endmacro

%macro cuatroDwordsACuatroBytes 1
	andps %1, xmm5
	pshufd xmm7, %1, 00001101b ; XMM7 =  000A 000A 000R 000B
	pshufd %1, %1, 00001000b   ;   %1 =  000A 000A 000G 000A
	
	PUNPCKLBW %1, xmm7   ; XMM7 =  000A 000A 000R 000B
	 				     ;   %1 =  000A 000A 000G 000A
	 					 ;   %1 =  00AA 00RG 0000 00BA
	 					 
	pshufd xmm7, %1, 10101010b  ;  XMM7 =  00RG 00RG 00RG 00RG
								; 	 %1 =  00AA 00RG 0000 00BA
	PUNPCKLWD %1, xmm7			;    %1 =  0000 RG00 0000 RGBA
	;movq xmm7,qword[shuffleDwordBajo] 
	;pshufb %1, xmm7
%endmacro



negative:
		push ebp
		mov ebp, esp
		sub esp, 8
		push edi
		push esi
		push ebx
		push ecx
		push edx

		
		mov ebx, h
		mov h_1, ebx
		dec h_1
		
		mov ebx, w
		mov w_1, ebx
		dec w_1
		
		shl ebx, 2			; ebx ---> 4 w
		shl w_1, 2
		
		
		mov esi, screen
		mov edi, esi		; edi ---> fila actual
		mov eax, esi
		sub esi, ebx		; esi ---> fila previa
		add eax, ebx		; eax ---> fila siguiente
		
	
		MOVss xmm4, [doscincocinco]
		shufps xmm4, xmm4, 0
		
		; la usaré para pasar de: XXXR XXXG XXXB XXXA
		;  a 000R 000G 000B 000A
		movdqu xmm5, [mascara_bytesBajos]

		movdqu xmm6, [mascara_dwordBajo]
		
		xorps xmm1, xmm1	; xmm1 = ARRIBA		al comenzar el ciclo es 0
		
		; itero sobre las filas        
		xor ecx, ecx			;i = 0
     	xor edx, edx			;j = 0
     	; xmm0 = IZQUIERDA     al comenzar una fila, es 0
		xorps xmm0, xmm0
		xorps xmm1, xmm1		
		
		; ------------------------ y = 0-----------------------------------
		
			.ciclo_columnas0:
					.cargarDerecha0:
						cmp edx, w_1
						je .derechaIgualCero0
							movd xmm3, [edi+edx+4]  ; xmm3 = DERECHA
							jmp .operacionesDeNegative0
							
							.derechaIgualCero0:
							xorps xmm3, xmm3
							
						.operacionesDeNegative0:
						; pasa de esto: 0000 0000 0000 RGBA
							cuatroBytesACuatroDwords xmm0
						; a esto:       000R 000G 000B 000A 
							cuatroBytesACuatroDwords xmm1
							cuatroBytesACuatroDwords xmm2
							cuatroBytesACuatroDwords xmm3										
						
						; convertir a flotantes (de precision simple)
						cvtdq2ps xmm0, xmm0
						cvtdq2ps xmm1, xmm1
						cvtdq2ps xmm2, xmm2
						cvtdq2ps xmm3, xmm3
						
						; realizar las operaciones de negative :S
						addps xmm0, xmm1
						addps xmm0, xmm2
						addps xmm0, xmm3
						addps xmm0, xmm4		; xmm0 = (ar + ab + iz + de + 255) por color
						divps xmm0, xmm4		; xmm0 = (ar/255 + ab/255 + iz/255 + de/255 + 1) por color
						rsqrtps xmm0, xmm0		; xmm0 = 1 / raiz { (ar/255 + ab/255 + iz/255 + de/255 + 1)  }   por color
						mulps xmm0, xmm4		; xmm0 = 1 / raiz { (ar/255 + ab/255 + iz/255 + de/255 + 1)  }  * 255 por color
					
						; convertir a enteros
						cvttps2dq xmm0, xmm0	; xmm0 = 4 dwords
						
						; juntar cuatro dwords (colores) en cuatro bytes (un pixel)
						; debe pasar de:  XXXR XXXG XXXB XXXA
						; a esta forma :  XXXX XXXX XXXX RGBA
						cuatroDwordsACuatroBytes xmm0
						
						; actualizar pixel
						movd [edi+edx], xmm0
					
						movd xmm0, [edi+edx]	; xmm0 = IZQUIERDA, de la proxima iteracion
						
						lea edx, [edx+4]
						cmp edx, ebx
						jne .ciclo_columnas0
				
				add esi, ebx	
				add edi, ebx
				add eax, ebx

				inc ecx
		; ------------------------  0 < y < h-1 -----------------------------------		
		; asumo que la imagen tiene al menos 2px de alto
		.ciclo_filas:
				xorps xmm0, xmm0
				xor edx, edx			;j = 0
				.ciclo_columnas:
					movd xmm1, [esi+edx]	; xmm1 = ARRIBA
					cmp ecx, h_1
						je .abajoIgualCero
								movd xmm2, [eax+edx]	; xmm2 = ABAJO
								jmp .cargarDerecha

								.abajoIgualCero:
								xorps xmm2, xmm2

						.cargarDerecha:
						cmp edx, w_1
						je .derechaIgualCero
							movd xmm3, [edi+edx+4]  ; xmm3 = DERECHA
							jmp .operacionesDeNegative
							
							.derechaIgualCero:
							xorps xmm3, xmm3

					.operacionesDeNegative:
						cuatroBytesACuatroDwords xmm0
						cuatroBytesACuatroDwords xmm1
						cuatroBytesACuatroDwords xmm2
						cuatroBytesACuatroDwords xmm3										
						cvtdq2ps xmm0, xmm0
						cvtdq2ps xmm1, xmm1
						cvtdq2ps xmm2, xmm2
						cvtdq2ps xmm3, xmm3
						addps xmm0, xmm1
						addps xmm0, xmm2
						addps xmm0, xmm3
						addps xmm0, xmm4		; xmm0 = (ar + ab + iz + de + 255) por color
						divps xmm0, xmm4		; xmm0 = (ar/255 + ab/255 + iz/255 + de/255 + 1) por color
						rsqrtps xmm0, xmm0		; xmm0 = 1 / raiz { (ar/255 + ab/255 + iz/255 + de/255 + 1)  }   por color
						mulps xmm0, xmm4		; xmm0 = 1 / raiz { (ar/255 + ab/255 + iz/255 + de/255 + 1)  }  * 255 por color
						cvttps2dq xmm0, xmm0	; convierte a entero
						cuatroDwordsACuatroBytes xmm0

						movd [edi+edx], xmm0
					
						movd xmm0, [edi+edx]	; xmm0 = IZQUIERDA, de la proxima iteracion
						
						lea edx, [edx+4]
						cmp edx, ebx
						jne .ciclo_columnas
			
				add esi, ebx	
				add edi, ebx
				add eax, ebx

				inc ecx				
				cmp ecx, h_1				
				jne .ciclo_filas
		; ------------------------  y = h-1 -----------------------------------	
				xorps xmm0, xmm0
				xorps xmm2, xmm2  ; ABAJO = 0
				xor edx, edx			
				.ciclo_columnas_h_1:
					movd xmm1, [esi+edx]	; xmm1 = ARRIBA
					cmp edx, w_1
					je .derechaIgualCero_h_1
						movd xmm3, [edi+edx+4]  ; xmm3 = DERECHA
						jmp .operacionesDeNegative_h_1
							
						.derechaIgualCero_h_1:
						xorps xmm3, xmm3

				.operacionesDeNegative_h_1:
					cuatroBytesACuatroDwords xmm0
					cuatroBytesACuatroDwords xmm1
					cuatroBytesACuatroDwords xmm2
					cuatroBytesACuatroDwords xmm3										
					cvtdq2ps xmm0, xmm0
					cvtdq2ps xmm1, xmm1
					cvtdq2ps xmm2, xmm2
					cvtdq2ps xmm3, xmm3
					addps xmm0, xmm1
					addps xmm0, xmm2
					addps xmm0, xmm3
					addps xmm0, xmm4		; xmm0 = (ar + ab + iz + de + 255) por color
					divps xmm0, xmm4		; xmm0 = (ar/255 + ab/255 + iz/255 + de/255 + 1) por color
					rsqrtps xmm0, xmm0		; xmm0 = 1 / raiz { (ar/255 + ab/255 + iz/255 + de/255 + 1)  }   por color
					mulps xmm0, xmm4		; xmm0 = 1 / raiz { (ar/255 + ab/255 + iz/255 + de/255 + 1)  }  * 255 por color
					cvttps2dq xmm0, xmm0	; convierte a entero
					cuatroDwordsACuatroBytes xmm0

					movd [edi+edx], xmm0
				
					movd xmm0, [edi+edx]	; xmm0 = IZQUIERDA, de la proxima iteracion
					
					lea edx, [edx+4]
					cmp edx, ebx
					jne .ciclo_columnas_h_1

			pop edx
			pop ecx
			pop ebx
			pop esi
			pop edi
			add esp, 8
			pop ebp
			ret
			

global  monocrome
%define screen_mono	dword[ebp+8]
%define w_mono		dword[ebp+12]
%define h_mono		dword[ebp+16]

section .data
coefRed: dd 0.299
coefGreen: dd 0.587
coefBlue: dd 0.114


section .text
monocrome:
			push ebp
			mov ebp, esp
			push ebx
			push esi
			push edi
			
			movss xmm0, [coefRed]
			pshufd xmm0, xmm0, 0x0
			movss xmm1, [coefGreen]
			pshufd xmm1, xmm1, 0x0
			movss xmm2, [coefBlue]
			pshufd xmm2, xmm2, 0x0
			
			mov esi, screen_mono
			
			mov ecx, h_mono
		.cicloColumnas:
			mov edx, w_mono
				
			.cicloFilas:

				;leo cuatro pixeles
				movdqu xmm3, [esi]
				

				movaps xmm4, xmm3
				movaps xmm5, xmm3
				
				; xmm3: rojo
				pslld xmm3, 24		;limpio los campos verde, azul y alfa
				psrld xmm3, 24		;lo ubico en el byte menos significativo
				CVTDQ2PS xmm3, xmm3
				mulps xmm3, xmm0
				
				; xmm3: verde
				psrld xmm4, 8		;limpio el campo rojo
				pslld xmm4, 24		;limpio el campo alfa y azul
				psrld xmm4, 24		;lo ubico en el byte menos significativo
				CVTDQ2PS xmm4, xmm4
				mulps xmm4, xmm1
				
				; xmm5: azul
				psrld xmm5, 16		;limpio los campos rojo y verde
				pslld xmm5, 24		;limpio el campo alfa
				psrld xmm5, 24		;lo ubico en el byte menos significativo
				CVTDQ2PS xmm5, xmm5
				mulps xmm5, xmm2
				
				; sumo los productos
				addps xmm3, xmm4
				addps xmm3, xmm5
				
				; convierto a entero
				CVTPS2DQ xmm3, xmm3
				pslld xmm3, 24
				psrld xmm3, 24			;lo ubico en campo R
				movaps xmm4, xmm3
				movaps xmm5, xmm3
				pslld xmm4, 8			;lo duplico en campo G
				orps xmm3, xmm4
				pslld xmm5, 16			;lo duplico en campo B
				orps xmm3, xmm5
				
				movups [esi], xmm3
				
				lea esi, [esi+16]
				
				lea edx, [edx-4]
				test edx, edx
				jnz .cicloFilas
			
			dec ecx
			jnz .cicloColumnas
				
			pop edi
			pop esi
			pop ebx
			pop ebp
			ret
		
